﻿#define  _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<ctype.h>//字符分类函数和字符转换函数的头文件
#include<assert.h>//断言函数头文件


/*函数分类函数*/

//islower函数判断字符字符为英文小写

//int main()
//{
//	//将字符串中的⼩写字⺟转⼤写，其他字符不变
//	int i = 0;
//	char arr[] = { "Hello World" };
//	while (arr[i])
//	{
//		char c = arr[i];
//		/*
//			判断字符是否是'a'-'z',如果是即返回真（非0），否则返回0
//		*/
//		if (islower(c))
//		{
//			c -= 32;
//		}
//		putchar(c);
//		i++;
//	}
//	return 0;
//}

//isupper函数判断字符是否为英文大写'A'-'Z',返回条件和islower相同

//int main()
//{
//	int i = 0;
//	char arr[] = { "hELLO wORLD" };
//	while (arr[i])
//	{
//		char c = arr[i];
//		/*
//			判断字符是否是'A'-'Z',如果是即返回真（非0），否则返回0
//		*/
//		if (isupper(c))
//		{
//			c += 32;
//		}
//		putchar(c);
//		i++;
//	}
//	 
//	return 0;
//}



//isdigit函数判断字符是否为数字字符'0'-'9'

//isxdigit函数判断内容是否为十六进制数

/*函数转换函数*/
//将传入字符有大写转小写:	int tolower ( int c );
//将传入字符有小写转大写:	int toupper ( int c );


//int main()
//{
//	//将传入字符有大写转小写:	int tolower ( int c );
//	int i = 0;
//	char arr[] = "ZXCVBNM";
//	while (arr[i])
//	{
//		char c = arr[i];
//		if (islower(c)==0)
//		{
//			c=tolower(c);
//		}
//		putchar(c);
//		i++;
//	}
//	return 0;
//}


//int main()
//{
//	//将传入字符有小写转大写:	int toupper ( int c );
//	int i = 0;
//	char arr[] = "zxcvbnm" ;
//	while (arr[i])
//	{
//		char c = arr[i];
//		if (islower(c))
//		{
//			c = toupper(c);
//		}
//		putchar(c);
//		i++;
//	}
//	return 0;
//}




/*字符串函数,头文件为<string.h>*/
#include<string.h>


/*1、strlen函数：size_t strlen ( const char * str );*/

//从给定位置起向后统计'\0'前字符数，返回值为无符号数(size_t)

//int main()
//{
//	char arr[] = "zxcvbnm";
//	size_t len = strlen(arr);
//	printf("%d", len);
//	return 0;
//}

/*strlen函数的模拟实现*/

//方法一：计数器法
//int my_strlen(const char* arr)
//{
// assert(arr);
//	int counst = 0;
//	while (*arr)
//	{
//		counst++;
//		arr++;
//	}
//	return counst;
//}

//递归方式实现
//int my_strlen(const char* arr)
//{
//	assert(arr);//arr指针不为空
//	if (*arr == '\0')
//	{
//		return 0;
//	}
//	else
//		return 1 + my_strlen(arr + 1);
//}

//指针-指针
//int my_strlen(const char* arr)
//{
//	assert(arr);
//	char* ret = arr;
//	while (*ret!='\0')
//	{
//		ret++;
//	}
//	return ret-arr;
//}
//
//
//int main()
//{
//	char arr[] = "zxcvbnm";
//	int len = my_strlen(arr);
//	printf("%d", len);
//	return 0;
//}


/*2、strcpy函数： char* strcpy(char * a2, const char * a1);*/

//注：
/*
	会将a1中所有字符拷贝到a2，包括'\0'
	a1（拷贝函数）必须为字符串，要包括'\0'
	a2（目标函数）空间必须足够大，且要能够修改
	不能将字符串拷贝到常量字符串上，如：char *p="zxcvbnm";
*/
//int main()
//{
//	char arr1[] = "zxcvbnm";
//	char arr2[100] = { 0 };
//	char* c = strcpy(arr2, arr1);//将arr1拷贝到arr2
//	printf("arr2=%s\n", c);
//	return 0;
//}

/*strcpy的模拟实现*/

//char* my_strcpy(char* a2, const char* a1)
//{
//	
//	assert(a1&&a2);
//	char* ret = a2;
//	/*while (*a1)
//	{
//		*a2 = *a1;
//		a1++;
//		a2++;
//	}*/
//	while (*a2++ = *a1++)
//	{
//		;
//	}
//	return ret;
//}
//
//int main()
//{
//	char arr1[] = "zxcvbnm";
//	char arr2[100] = { 0 };
//	char* c = my_strcpy(arr2, arr1);//将arr1拷贝到arr2
//	printf("arr2=%s\n", c);
//	return 0;
//}


/*3、strcat函数：char* strcat(char* c1,const char* c2)*/
//将c2追加到c1后面
/*步骤：
	1、找到c1指向空间中第一个'\0'
	2、然后从这个'\0'开始追加c2
	3、c2指向空间内容包括'\0'都会追加到c1
*/

/*注：
	c1指向空间必须足够长且可以修改
	当c1给c1自己追加时,strcat(c1,c1)会将c1中'\0'给覆盖掉，所以一般不会用strcat自己给自己追加，而是用strncat函数
*/

//int main()
//{
//	char arr1[100] = "abcd";//c1指向空间必须足够长且可以修改
//	char arr2[] = "efgh";
//	strcat(arr1, arr2);
//	printf("%s\n", arr1);
//	return 0;
//}

/*strcat的模拟实现*/

//char* my_strcat(char* a1, const char* a2)
//{
// assert(a1&&a2);
//	char* ret = a1;
//	while(*a1)
//	{
//		a1++;
//	}
//	/*while (*a2)
//	{
//		*a1++ = *a2++;
//	}*/
//	while ((*a1++ = *a2++))
//	{
//		;
//	}
//	return ret;
//}
//
//int main()
//{
//	char arr1[100] = "abcd";//c1指向空间必须足够长且可以修改
//	char arr2[] = "efgh";
//	my_strcat(arr1, arr2);
//	printf("%s\n", arr1);
//	return 0;
//}


/*4、strcmp函数：int strcmp(const char* c1,const char* c2)*/
//进行c1和c2两个字符串中对应位置字符的ascII码大小比较


/*
	c1>c2：返回大于0的值
	c1=c2：返回0
	c1<c2：返回小于0的值
*/


//int main()
//{
//	char arr1[] = "abcdefg";
//	char arr2[] = "abcddef";
//	if (strcmp(arr1, arr2) == 0)
//	{
//		printf("arr1==arr2\n");
//	}
//	else if (strcmp(arr1, arr2) > 0)
//	{
//		printf("arr1>arrr2\n");
//	}
//	else
//	{
//		printf("arr1 < arr2\n");
//	}
//
//	return 0;
//}

/*strcmp的模拟实现*/
//int my_strcmp(const char* a1, const char* a2)
//{
//	assert(a1 && a2);
//	while (*a1 == *a2)
//	{
//		if (*a1 == '\0')//当其中一个加到'\0'时则另一个也是加到'\0',这时两个字符串就相等
//		{
//			return 0;
//		}
//		a1++;
//		a2++;
//	}
//	return *a1 - *a2;
//
//}
//
//
//int main()
//{
//	char arr1[] = "abcdefg";
//	char arr2[] = "abcddef";
//	if (my_strcmp(arr1, arr2) == 0)
//	{
//		printf("arr1==arr2\n");
//	}
//	else if (my_strcmp(arr1, arr2) > 0)
//	{
//		printf("arr1>arrr2\n");
//	}
//	else
//	{
//		printf("arr1 < arr2\n");
//	}
//
//	return 0;
//}



/*5、strncpy：char * strncpy ( char * c1, const char * c2, size_t num );*/
//从c2中拷贝num个字符到c1
//这个函数可以控制拷贝的字符个数

/*注：当要拷贝的字符个数大于c2（被拷贝字符串）的长度时，后面自动补0直到满足num个*/

//int main()
//{
//	char arr1[] = "abcdef";
//	char arr2[100] = { 0 };
//	char* c = strncpy(arr2, arr1, 3);
//	printf("%s\n", c);
//	return 0;
//}

/*6、strncat函数：char * strncat(char* c1,const char* c2,size_t num)*/
//在c1指向字符串后面追加num个字符，再追加⼀个 \0 
//这里的num为最多比较字符个数
//注：如果c2 指向的字符串的⻓度⼩于num的时候，只会将字符串中到\0 的内容追加到c1指向的字符串末尾

//int main()
//{
//	char arr1[100] = "abcdefg";
//	char arr2[] = "abcdefg";
//	strncat(arr1, arr2, 5);
//	printf("%s", arr1);
//
//	return 0;
//}

/*7、strncmp函数：int strncmp(const char* c1,const char* c2,size_t num);*/
//c1指向字符串与c2指向字符串进行比较num个字符

//int main()
//{
//	char arr1[100] = "abcdefg";
//	char arr2[] = "abccegf";
//	if (strncmp(arr1, arr2, 5) == 0)
//	{
//		printf("arr1==arr2\n");
//	}
//	else if (strncmp(arr1, arr2, 5) > 0)
//	{
//		printf("arr1>arr2\n");
//	}
//	else
//	{
//		printf("arr1<arr2\n");
//	}
//	return 0;
//}


/*8、strstr函数：const char* strstr(const char * str1,const char* str2);*/
//在一个字符串中找一个子字符串，找出第一次出现的地址
//如果找到了，就返回第一次出现的地址
//如果找不到就返回NULL

//int main()
//{
//	char arr1[] = "abccdef";
//	char arr2[] = "abc";
//	char* ret = strstr(arr1, arr2);
//	if ( ret == NULL)
//	{
//		printf("没有找到\n");
//	}
//	else
//	{
//		printf("找到了：%s", ret);
//	}
//	return 0;
//}

/*strstr函数的模拟实现*/

//const char* my_strstr(const char* str1, const char* str2)
//{
//	assert(*str1 && *str2);
//	const char* s1 = str1;
//	const char* s2 = str2;
//	const char* flag = str1;//记录开始匹配的位置
//	if (*str2 == '\0')//当str2为空时
//	{
//		return str1;
//	}
//	while (*flag)
//	{
//		s1 = flag;
//		s2 = str2;
//		while (*s1&&*s2&&*s1 == *s2)
//		{
//			s1++;
//			s2++;
//		}
//		if (*s2 == '\0')
//		{
//			return	flag;
//		}
//		flag++;
//	}
//	return NULL;
//}
//
//int main()
//{
//	char arr1[] = "abccdef";
//	char arr2[] = "cde";
//	char* ret = my_strstr(arr1, arr2);
//	if (ret == NULL)
//	{
//		printf("没有找到\n");
//	}
//	else
//	{
//		printf("找到了：%s", ret);
//	}
//	return 0;
//}


/*9、strtok函数：char * strtok ( char * str, const char * sep); */

//strtok函数找到str中的一个标记，并用'\0'结尾，返回一个指向该标记的指针
//sep是一个指向定于了分隔符字符的集合的指针
//因为strtok函数会改变str的内容，所以strtok一般处理的是临时拷贝的内容并且可以被修改
/*
strtok函数的第⼀个参数不为NULL ，函数将找到str中第⼀个标记，strtok函数将保存它在字符串中的位置。
strtok函数的第⼀个参数为NULL ，函数将在同⼀个字符串中被保存的位置开始，查找下⼀个标记。
如果字符串中不存在更多的标记，则返回NULL 指针。
*/

//int main()
//{
//	char arr[] = "192.168.6.111";
//	char* sep = ".";
//	char* str = NULL;
//	for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
//	{
//		printf("%s\n", str);
//	}
//	return 0;
//}

/*10、strerror函数： char* strerror ( int errnum );*/

/*strerror 函数可以把参数部分错误码对应的错误信息的字符串地址返回来。
在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码，⼀般是放在errno.h这个头⽂件中说明
的，C语⾔程序启动的时候就会使⽤⼀个全局的变量errno来记录程序的当前错误码，只不过程序启动
的时候errno是0，表⽰没有错误，当我们在使⽤标准库中的函数的时候发⽣了某种错误，就会将对应
的错误码，存放在errno中，⽽⼀个错误码的数字是整数很难理解是什么意思，所以每⼀个错误码都是
有对应的错误信息的。strerror函数就可以将错误对应的错误信息字符串的地址返回。*/ 


/*
	注：当发生多次错误时，上次错误的errno值会被下一次错误的errno覆盖
*/
#include<errno.h>
//int main()
//{
//	int i = 0;
//	for (i = 0; i <= 10; i++) {
//		printf("%s\n", strerror(i));
//	}
//	return 0;
//}

int main()
{
	FILE* pFile;
	pFile = fopen("unexist.ent", "r");
	/*if (pFile == NULL)
		printf("Error opening file unexist.ent: %s\n", strerror(errno));*/
	if (pFile == NULL)
		perror("Error opening file unexist.ent");
	return 0;
}

/*
	perror会直接将错误信息打印出来，连errno都不需要输入
	void perror(const char* str);
*/